package com.zed.code.service.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zed.code.base.TResponse;
import com.zed.code.util.GDEVConfig;
import com.zed.code.util.PubFetchTool;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.List;

/**
 *对供应商回调的信息进行解密
 *
 */

@ControllerAdvice("com.zed.code.controller")
public class IRequestBodyAdvice implements RequestBodyAdvice {
    public static final String OPERATOR_ID = "765367656";//运营商编号
    private static final Logger logger = LoggerFactory.getLogger(IRequestBodyAdvice.class);

    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> httpMessageConverterType) {
        return AbstractJackson2HttpMessageConverter.class.isAssignableFrom(httpMessageConverterType);
    }

    public Object handleEmptyBody(Object object, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> httpMessageConverterType) {
        return object;
    }

    public HttpInputMessage beforeBodyRead(final HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> httpMessageConverterType)
            throws IOException {

        if (!"queryToken".equals(methodParameter.getMethod().getName())){//不等于获取token
            List<String> authorization=httpInputMessage.getHeaders().get("Authorization");
            logger.info("com.zed.code.controller.notify Authorization:{}", JSON.toJSONString(authorization));
            TResponse tResponse= PubFetchTool.reqRet(authorization);
            if (tResponse!=null){
                logger.error("token无效");
                throw new IOException("token无效");
            }
        }
        return new HttpInputMessage() {

            public InputStream getBody() throws IOException {
                String reqJsonStr = IOUtils.toString(httpInputMessage.getBody(), "UTF-8");
                logger.info("接口入参body:{}", reqJsonStr);
                JSONObject json = JSONObject.parseObject(reqJsonStr);
               //对供应商传来的信息进行签名校验
                boolean checkSig = PubFetchTool.checkSig(json, OPERATOR_ID, GDEVConfig.SIGN_KEY);
                if (!checkSig) {
                    json.put("Sig", "CHECK_SIG_ERROR");
                } else {
                    //对供应商传来的信息进行解密
                    String data = PubFetchTool.genDDDecodeData(json.getString("Data"),GDEVConfig.AES_KEY,GDEVConfig.AES_IV);
                    logger.info("解密后的data:{}", data);
                    JSONObject datajson = JSONObject.parseObject(data);
                    datajson.put("OperatorID", OPERATOR_ID);
                    if (datajson.containsKey("ConnectorStatusInfo")) {
                        json.put("Data", datajson.getJSONObject("ConnectorStatusInfo"));
                    } else {
                        json.put("Data", datajson);
                    }

                }
                logger.info("com.zed.code.controller.notify com.zed.code.request json:{}", json);
                return IOUtils.toInputStream(json.toJSONString(), "UTF-8");
            }

            public HttpHeaders getHeaders(){


                return httpInputMessage.getHeaders();
            }
        };
    }

    public Object afterBodyRead(Object object, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> httpMessageConverterType) {
        return object;
    }
}
